Scroll to navigation

OPEN(2) Системные вызовы OPEN(2)

НАЗВАНИЕ

open, creat -- открыть и, вероятно, создать файл или устройство

КРАТКАЯ СВОДКА

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
int creat(const char *pathname, mode_t mode);

ОПИСАНИЕ

Системный вызов open превращает имя файла в дескриптор файла (небольшое неотрицательное число, используемое при последующем вводе-выводе, например, с read, write, и т. п. Если системный вызов завершается успешно, возвращенный файловый дескриптор является самым маленьким дескриптором, который еще не открыт процессом. В результате этого вызова появляется новый открытый файл, не разделяемый ни с каким процессом (разделяемые открытые файлы могут возникнуть в результате системного вызова fork(2). Новый файловый дескриптор будет оставаться открытым при выполнении функции exec(2) (смотри описание fcntl(2)). Указатель в файле устанавливается в начало.

Параметр flags -- это O_RDONLY, O_WRONLY или O_RDWR, задающие, соответственно, открытие файла только для чтения, только для записи и для чтения и записи, которые можно комбинировать с помощью логического ИЛИ с нулем или более нижеследующих флагов:

Если файл не существует, то он будет создан. Владелец (uid) файла устанавливается в фактический идентификатор владельца процесса. Группа (gid) устанавливается либо в фактический идентификатор группы процесса или же в идентификатор группы родительского каталога (зависит от типа файловой системы и флагов программы mount, а также прав доступа к родительскому каталогу. См., например, флаги bsdgroups и sysvgroups в файловой системе ext2, которые описаны в mount(8)).
Если используется совместно с O_CREAT, то если файл уже существует, то open завершится с ошибкой. В этом контексте символьная ссылка существует, независимо от того, куда она указывает. O_EXCL не работает на файловых системах NFS, а в программах, полагающихся на этот флаг для реализации блокировки, возникнет race condition. Решение для атомарной блокировки с помощью файла: создать файл с уникальным именем на той же самой файловой системе (это имя может содержать, например, имя машины и идентификатор процесса), использовать link(2), чтобы создать ссылку на файл блокировки. Если link() возвращает 0, значит, блокировка была успешной. В противном случае используйте stat(2), чтобы убедиться, что количество ссылок на уникальный файл возросло до двух, что опять означает, что блокировка была успешной.
Если pathname ссылается на терминальное устройство — см. tty(4), — то оно не станет контролирующим терминалом процесса, даже если у этого процесса нет такового.
Если файл уже существует, является обычным файлом, а режим открытия позволяет запись (то бишь это O_RDWR или O_WRONLY), то он будет обрезан до нулевой длины. Если файл является FIFO или устройством терминала, то флаг O_TRUNC игнорируется. В противном случае действие O_TRUNC не описано. (На многих версиях Linux этот флаг будет игнорирован; на других версиях будет возвращена ошибка.)
Файл открывается в режиме добавления. Перед каждым write, файловый указатель перемещается в конец файла, как если бы использовался lseek. O_APPEND может привести к повреждению файлов на файловой системе NFS, если несколько процессов одновременно добавляют данные в один файл. Это происходит из-за того, что NFS не поддерживает добавление в файл, поэтому ядро на машине-клиенте должно эмулировать эту поддержку, что не может быть выполнено без race condition.
Если возможно, то файл открывается в неблокирующем режиме. Ни open, ни другие последующие операции над возвращенным дескриптором файла не заставят вызывающий процесс ждать. Работа с каналами FIFO также описана в fifo(4). Этот режим не обязан как-либо действовать на файлы, не являющиеся FIFO.
Файл открывается в режиме синхронного ввода-вывода. Все вызовы write для соответствующего дескриптора файла блокируют вызывающий процесс до тех пор, пока данные не будут физически записаны оборудованием, на котором находится файл. Однако же, смотри в разделе ОГРАНИЧЕНИЯ.
Если pathname -- это символическая ссылка, то open завершается с кодом ошибки. Это расширение из FreeBSD, которое было добавлено в Linux в версии 2.1.126. Все прочие символические ссылки в имени будут обработаны как обычно. Заголовочные файлы из glibc 2.0.100 и позже содержат определение этого флага; ядра с версиями меньше, чем 2.1.126, игнорируют этот флаг.
Если pathname не является каталогом, то open завершится с кодом ошибки. Этот флаг используется только в Linux, и был добавлен в ядре 2.1.126, чтобы избежать проблем с атаками типа "отказ обслуживания", если opendir(2) был вызван с каналом FIFO или ленточным устройством. Этот флаг не следует использовать вне реализации opendir.
На 32-битных системах, поддерживающих Большие Файловые Системы, этот флаг позволяет открывать файлы, длина которых не помещается в 31 бит.

Некоторые из вышеописанных флагов могут быть изменены после открытия файла с помощью fctnl.

Аргумент mode задает права доступа, которые используются в случае создания нового файла. Они модифицируются обычным способом, используя umask процесса: права доступа свежесозданного файла равны (mode & ~umask). Заметьте, что этот режим доступа относится только к последующим обращениям к свежесозданному файлу; системный вызов open, который создает новый файл только для чтения, вполне может вернуть файловый дескриптор для чтения/записи.

Нижеследующие символические константы можно использовать в mode:

00700 пользователь (владелец файла) имеет права чтения, записи и выполнения.
00400 пользователь имеет право чтения
00200 пользователь имеет право записи
00100 пользователь имеет право выполнения
00070 группа имеет права чтения, записи и выполнения
00040 группа имеет право чтения
00020 группа имеет право записи
00010 группа имеет право выполнения
00007 все остальные имеют права чтения, записи и выполнения
00004 все остальные имеют право чтения
00002 все остальные имеют право записи
00001 все остальные имеют право выполнения

mode всегда должен быть указан при использовании O_CREAT, во всех остальных случаях этот параметр игнорируется.

creat эквивалентен open с flags, равными O_CREAT | O_WRONLY | O_TRUNC.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

open и creat возвращают новый дескриптор файла, или -1, если произошла ошибка (в этом случае errno устанавливается должным образом). Заметьте, что open может открывать файлы устройств, но creat не может создавать их -- используйте для этого mknod(2).

На файловых системах NFS с включенным преобразованием идентификаторов пользователей open может вернуть файловый дескриптор, но, например, read(2) вернет ошибку EACCES. Это из-за того, что клиент выполняет open, проверяя права доступа, но преобразование идентификаторов производится сервером при запросах на чтение и запись.

Если файл только что создан, его atime, ctime и mtime, а также ctime и mtime родительского каталога, установлены в текущее время, В противном случае если файл модифицирован из-за флага O_TRUNC, его поля ctime и mtime устанавливаются в текущее время.

ОШИБКИ

pathname уже существует, и были использованы O_CREAT и O_EXCL.
pathname ссылается на каталог, а тип доступа подразумевает запись.
Запрошенный доступ к файлу не разрешен, или же один из каталогов в pathname не позволяет поиск (выполнение), или же файл еще не существует, а доступ для записи в родительский каталог не разрешен. error_ENAMETOOLONG(pathname) error_ENOENT(pathname)
Компонент, использованный как каталог в pathname, таковым не является, или был указан флаг O_DIRECTORY, а pathname не является каталогом.
Установлены O_NONBLOCK | O_WRONLY, файл является каналом FIFO, но нет процессов, которые открыли этот канал для чтения. Возможно также, что файл является файлом устройства, но соответствующее устройство не установлено.
pathname ссылается на файл устройства, но соответствующего устройства не существует. (Это ошибка в ядре Linux: должен возвращаться ENXIO.)
pathname ссылается на файл, находящийся на файловой системе, смонтированной только для чтения, и был запрошен доступ для записи.
pathname ссылается на исполняемый файл, который в настоящее время исполняется, и был запрошен доступ для записи. error_EFAULT(pathname)
Слишком много символических ссылок было пройдено при обнаружении pathname, или был указан флаг O_NOFOLLOW, а pathname является символической ссылкой.
pathname нужно было создать на устройстве, на котором не было места для нового файла. error_ENOMEM
Процесс уже открыл максимально допустимое количество файлов.
Достигнут предел на максимальное общее количество файлов, открытых в системе.

СООТВЕТСТВИЕ СТАНДАРТАМ

SVr4, SVID, POSIX, X/OPEN, BSD 4.3 Флаги O_NOFOLLOW и O_DIRECTORY специфичны для Linux. Для того, чтобы получить их определение, может потребоваться определить (через #define) символ _GNU_SOURCE.

ОГРАНИЧЕНИЯ

В протоколе, на котором работает NFS, существует множество недоработок, в числе прочего, оказывающих влияние на O_SYNC и O_NDELAY.

POSIX предоставляет три разных варианта синхронного ввода-вывода, соответствующего флагам O_SYNC, O_DSYNC и O_RSYNC. В настоящее время (версия 2.1.130), все они являются синонимами под Linux.

СМОТРИ ТАКЖЕ

read(2), write(2), fcntl(2), close(2), link(2), mknod(2), mount(2), stat(2), umask(2), unlink(2), socket(2), fopen(3), fifo(4)

ПЕРЕВОД

Copyright (C) Alexey Mahotkin <alexm@hsys.msk.ru> 1999-2001

June 3, 1999 Linux